package com.axend.lib_base.help.ble

import cn.com.heaton.blelibrary.ble.utils.ByteUtils
import com.axend.lib_base.help.ble.enums.BleCommandTag
import com.axend.lib_base.utils.ByteUtil
import com.axend.lib_base.utils.log.MyLogUtils
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer

/**
 * @author axend
 * @date 2022/3/28
 * @desc 蓝牙消息处理
 */
object BleMsgProcessor {
    private val messageMagicHeader: ByteArray = byteArrayOf(
        0xAA.toByte(),
        0xAA.toByte(), 0x55, 0x55
    )

    private var buffer: ByteArray = ByteArray(0)

    /**
     * 消息编码
     */
    fun encodeMsg(msg: Any, bleCommandTag: BleCommandTag): ByteArray {
        val outPutStream = ByteArrayOutputStream()

        /*先写入消息头*/
        outPutStream.write(messageMagicHeader)
        /*再写入消息长度content len 按小端处理*/
        /* 将 msg 转换为字节数组 */
        val msgBytes: ByteArray = when (msg) {
            is ByteArray -> msg
            is String -> msg.toByteArray(Charsets.UTF_8)
            is Int -> ByteUtil.intToByteLittle(msg)
            is Float -> ByteUtil.floatToByte4Little(msg)
            is Short -> ByteUtil.shortToByteLittle(msg)
            is UInt -> ByteUtil.intToByteLittle(msg.toInt())
            else -> throw IllegalArgumentException("Unsupported message type")
        }
        /* 获取消息长度 */
        val contentLength: Short = (msgBytes.size + 2).toShort()
        outPutStream.write(ByteUtil.shortToByteLittle(contentLength))
        /*再写入标识符*/
        outPutStream.write(bleCommandTag.getMarkByteArray())
        outPutStream.write(msgBytes)
        return outPutStream.toByteArray()
    }


    /**
     * 消息解码
     */
    fun decodeMsg(msg: ByteArray): Pair<BleCommandTag, ByteArray>? {
        //将msg写入缓冲区
        val byteBuffer = ByteArrayInputStream(msg)
        //移动指针位置到第6位
        byteBuffer.skip(6)
        // 读取标识符（假设标识符是 2 字节）
        val markLow = byteBuffer.read()
        val markHigh = byteBuffer.read()
        if (markLow == -1 || markHigh == -1) {
            // 如果读取失败，返回 null
            return null
        }
        val markLowUnsigned = markLow and 0xFF
        val bleCommandTag = BleCommandTag.fromId(markLowUnsigned) ?: return null
        //读取剩余的全部字节
        val remainingBytes = ByteBuffer.wrap(msg).array().copyOfRange(8, msg.size)
//        MyLogUtils.d("decodeMsg:bleCommandTag -$bleCommandTag, remainingBytes -${remainingBytes.contentToString()}")
        // 返回命令标识符和消息内容
        return Pair(bleCommandTag, remainingBytes)

    }


    /**
     * 固件内容编码
     */
    fun encodeFirmwareUpdateMsg(msg: ByteArray, bleCommandTag: BleCommandTag): ByteArray {
        val outPutStream = ByteArrayOutputStream()
        /*先写入消息头*/
        outPutStream.write(messageMagicHeader)
        when (bleCommandTag) {
            BleCommandTag.FW_UPGRADE_NOTIFY -> {
                /*消息长度 */
                outPutStream.write(byteArrayOf(0x06, 0x00))
                /*再写入标识符*/
                outPutStream.write(bleCommandTag.getMarkByteArray())
                outPutStream.write(msg)
            }

            BleCommandTag.FW_CONTENT -> {
                /* 获取消息长度 */
                val contentLength: Short = (msg.size + 2).toShort()
                outPutStream.write(ByteUtil.shortToByteLittle(contentLength))
                /*再写入标识符*/
                outPutStream.write(bleCommandTag.getMarkByteArray())
                outPutStream.write(msg)
            }

            BleCommandTag.FW_UPDATE_SUCCESS -> {
                /*消息长度 */
                outPutStream.write(byteArrayOf(0x06, 0x00))
                /*再写入标识符*/
                outPutStream.write(bleCommandTag.getMarkByteArray())
                outPutStream.write(bleCommandTag.getMarkFixCommand())
            }

            else -> {

            }
        }
        return outPutStream.toByteArray()
    }


    fun decodeFirmwareUpdateMsg(msg: ByteArray): Pair<BleCommandTag, ByteArray>? {
        // 将新接收到的数据添加到缓冲区
        buffer += msg
        // 检查缓冲区中的数据是否足够
        if (buffer.size < 12) {
            // 记录此次数据到缓冲区
            return null
        }
        if (buffer.size >= 24) {
            //则取buffer最后十二位字节
            buffer = buffer.copyOfRange(buffer.size - 12, buffer.size)
        }
        //将msg写入缓冲区
        val byteBuffer = ByteArrayInputStream(buffer)
        //移动指针位置到第5位
        byteBuffer.skip(6)
        // 读取标识符（假设标识符是 2 字节）
        val markLow = byteBuffer.read()
        val markHigh = byteBuffer.read()
        if (markLow == -1 || markHigh == -1) {
            // 如果读取失败，返回 null
            return null
        }

        val bleCommandTag =
            BleCommandTag.fromMark(byteArrayOf(markLow.toByte(), markHigh.toByte())) ?: return null
        //读取剩余的全部字节
        val remainingBytes = ByteBuffer.wrap(buffer).array().copyOfRange(8, buffer.size)
        // 更新缓冲区，去除已处理的数据
        buffer = buffer.copyOfRange(remainingBytes.size + 8, buffer.size)
        // 返回命令标识符和消息内容
        return Pair(bleCommandTag, remainingBytes)
    }


}